package com.nyt.report.util;

import java.io.*;
import java.net.URLDecoder;
import java.nio.file.FileAlreadyExistsException;
import java.util.*;

/**
 *
 *
 */
public abstract class FileUtil {

    /**
     * 文件类型Map
     */
    public final static Map<String, String> FILE_TYPE_MAP = new HashMap<String, String>();


    /**
     * 创建文件夹
     *
     * @param path
     * @throws FileAlreadyExistsException
     */
    public static File createDirs(String path) throws IOException {
        File file = new File(path);
        if (!file.exists()) {   // 不存在则创建
            file.mkdirs();
        }
        else {
            if (!file.isDirectory()) {   // 存在的不是文件夹,则把已存在更名，并创建文件夹
                //file.renameTo(new File(path+"_old_"+ DateUtil.dateFormat(new Date(), "yyyyMMdd")));
                //file.mkdirs();
                throw new FileAlreadyExistsException("Same Name File Has Already Exists");
            }
        }
        return file;
    }

    /**
     * 创建文件
     *
     * @param path
     * @throws IOException
     */
    public static File createFile(String path) throws IOException {
        File file = new File(path);
        if (!file.exists()) {   // 不存在则创建
            file.createNewFile();
        }
        else {
            //if (file.isDirectory()) {   // 存在的是文件夹,则把已存在更名，并创建文件夹
            //    file.renameTo(new File(path+"_old_"+ DateUtil.dateFormat(new Date(), "yyyyMMdd")));
            //    file.createNewFile();
            //}
            throw new FileAlreadyExistsException("Same Name File Has Already Exists");
        }
        return file;
    }

    public static File renameFile(String oldPath, String newPath) throws FileNotFoundException {
        File file = new File(oldPath);
        File newFile = new File(newPath);
        if (file.exists()) {   // 不存在则创建
            if (file.renameTo(newFile));
                return newFile;
        }
        throw new FileNotFoundException("File Not Found When Rename File");
    }

    /*读取文件的字节数组*/
    public static byte[] getFileByte(File file) throws IOException {
        File f = file;
        if (!f.exists()) {
            throw new FileNotFoundException("file not exists");
        }
        ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
        BufferedInputStream in = null;
        try {
            in = new BufferedInputStream(new FileInputStream(f));
            int buf_size = 1024;
            byte[] buffer = new byte[buf_size];
            int len = 0;
            while (-1 != (len = in.read(buffer, 0, buf_size))) {
                bos.write(buffer, 0, len);
            }
            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            bos.close();
        }
    }

    /*读取文件的字节数组*/
    public static byte[] getFileByte(InputStream is) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        BufferedInputStream in = null;
        try {
            in = new BufferedInputStream(is);
            int buf_size = 1024;
            byte[] buffer = new byte[buf_size];
            int len = 0;
            while (-1 != (len = in.read(buffer, 0, buf_size))) {
                bos.write(buffer, 0, len);
            }
            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            bos.close();
        }
    }

    /**
     * 从配置文件中读取参数（properties)
     *
     * @param confFilePath
     * @return
     * @throws IOException
     */
    public static Hashtable loadFromFile(String confFilePath) {
        // 读取配置文件
        InputStream in = null;
        try {
            if (confFilePath.contains("classpath:")) {
                String path = URLDecoder.decode(Class.class.getProtectionDomain().getCodeSource().getLocation().toString(),"UTF-8");
                path=path.substring(6);
                confFilePath = confFilePath.replace("classpath:",URLDecoder.decode(path,"UTF-8"));
            }
            in = loadFromOsFileSystemOrClasspathAsStream(confFilePath);
            return readToParamTable(in);
        }
        catch (Exception var12) {
            var12.printStackTrace();
            return null;
        }
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception var11) {
                var11.printStackTrace();
            }
        }
    }

    public static Hashtable readToParamTable(InputStream in) {
        Hashtable paramTable = new Hashtable();
        if (in != null) {
            InputStreamReader inReader = null;
            BufferedReader bufferedReader = null;

            try {
                inReader = new InputStreamReader(in);
                bufferedReader = new BufferedReader(inReader);

                String line;
                while((line = bufferedReader.readLine()) != null) {
                    line = line.trim();
                    if (line.length() != 0 && line.charAt(0) != '#') {
                        String[] parts = line.split("=", 2);
                        if (parts.length == 2) {
                            String name = parts[0].trim();
                            String value = parts[1].trim();
                            Object obj = paramTable.get(name);
                            if (obj == null) {
                                paramTable.put(name, value);
                            } else {
                                ArrayList valueList;
                                if (obj instanceof String) {
                                    valueList = new ArrayList();
                                    valueList.add(obj);
                                    valueList.add(value);
                                    paramTable.put(name, valueList);
                                } else {
                                    valueList = (ArrayList)obj;
                                    valueList.add(value);
                                }
                            }
                        }
                    }
                }
            } catch (Exception var19) {
                var19.printStackTrace();
            } finally {
                try {
                    if (bufferedReader != null) {
                        bufferedReader.close();
                    }

                    if (inReader != null) {
                        inReader.close();
                    }
                } catch (Exception var18) {
                    var18.printStackTrace();
                }
            }
        }
        return paramTable;
    }

    public static ClassLoader classLoader() {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        if (loader == null) {
            loader = ClassLoader.getSystemClassLoader();
        }

        return loader;
    }

    public static InputStream loadFromOsFileSystemOrClasspathAsStream(String filePath) {
        Object in = null;

        try {
            if ((new File(filePath)).exists()) {
                in = new FileInputStream(filePath);
            } else {
                in = classLoader().getResourceAsStream(filePath);
            }
        } catch (Exception var3) {
            var3.printStackTrace();
        }

        return (InputStream)in;
    }


    /**
     * 通过读取文件头部获得文件类型
     * @param file
     * @return 文件类型
     */
    public static String getFileType(File file) {
        getAllFileType();
        String fileExtendName = null;
        FileInputStream is;
        try {
            is = new FileInputStream(file);
            byte[] b = new byte[16];
            is.read(b,0, b.length);
            String filetypeHex = String.valueOf(bytesToHexString(b));
            Iterator<Map.Entry<String, String>> entryiterator = FILE_TYPE_MAP.entrySet().iterator();
            while (entryiterator.hasNext()) {
                Map.Entry<String,String> entry = entryiterator.next();
                String fileTypeHexValue = entry.getValue();
                if (filetypeHex.toUpperCase().startsWith(fileTypeHexValue)) {
                    fileExtendName = entry.getKey();
                    is.close();
                    break;
                }
            }

            // 如果不是上述类型，则判断扩展名
            if(fileExtendName == null)
            {
                String fileName = file.getName();
                // 如果无扩展名，则直接返回空串
                if(-1 == fileName.indexOf("."))
                {
                    return "";
                }
                // 如果有扩展名，则返回扩展名
                return fileName.substring(fileName.indexOf(".") + 1);
            }
            is.close();
            return fileExtendName;
        } catch (Exception exception) {
            return null;
        }
    }

    /**
     * 获得文件头部字符串
     * @param src
     * @return
     */
    private static String bytesToHexString(byte[] src){
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }


    /*-----------------------------目前可以识别的类型----------------------------*/
    private static void getAllFileType()
    {
        FILE_TYPE_MAP.put("jpg", "FFD8FF"); //JPEG
        FILE_TYPE_MAP.put("png", "89504E47"); //PNG
        FILE_TYPE_MAP.put("gif", "47494638"); //GIF
        FILE_TYPE_MAP.put("tif", "49492A00"); //TIFF
        FILE_TYPE_MAP.put("bmp", "424D"); //Windows Bitmap
        FILE_TYPE_MAP.put("dwg", "41433130"); //CAD
        FILE_TYPE_MAP.put("html", "68746D6C3E"); //HTML
        FILE_TYPE_MAP.put("rtf", "7B5C727466"); //Rich Text Format
        FILE_TYPE_MAP.put("xml", "3C3F786D6C");
        FILE_TYPE_MAP.put("zip", "504B0304");
        FILE_TYPE_MAP.put("rar", "52617221");
        FILE_TYPE_MAP.put("psd", "38425053"); //PhotoShop
        FILE_TYPE_MAP.put("eml", "44656C69766572792D646174653A"); //Email [thorough only]
        FILE_TYPE_MAP.put("dbx", "CFAD12FEC5FD746F"); //Outlook Express
        FILE_TYPE_MAP.put("pst", "2142444E"); //Outlook
        FILE_TYPE_MAP.put("doc", "D0CF11E0"); //office类型，包括doc、xls和ppt
        FILE_TYPE_MAP.put("xls", "D0CF11E0");
        // FILE_TYPE_MAP.put("ppt", "D0CF11E0");
        FILE_TYPE_MAP.put("docx", "504B0304");  // 2007以上版本
        FILE_TYPE_MAP.put("xlsx", "504B0304");
        // FILE_TYPE_MAP.put("pptx", "504B0304");
        FILE_TYPE_MAP.put("mdb", "000100005374616E64617264204A"); //MS Access
        FILE_TYPE_MAP.put("wpd", "FF575043"); //WordPerfect
        FILE_TYPE_MAP.put("eps", "252150532D41646F6265");
        FILE_TYPE_MAP.put("ps", "252150532D41646F6265");
        FILE_TYPE_MAP.put("pdf", "255044462D312E"); //Adobe Acrobat
        FILE_TYPE_MAP.put("qdf", "AC9EBD8F"); //Quicken
        FILE_TYPE_MAP.put("pwl", "E3828596"); //Windows Password
        FILE_TYPE_MAP.put("wav", "57415645"); //Wave
        FILE_TYPE_MAP.put("avi", "41564920");
        FILE_TYPE_MAP.put("ram", "2E7261FD"); //Real Audio
        FILE_TYPE_MAP.put("rm", "2E524D46"); //Real Media
        FILE_TYPE_MAP.put("mpg", "000001BA"); //
        FILE_TYPE_MAP.put("mov", "6D6F6F76"); //Quicktime
        FILE_TYPE_MAP.put("asf", "3026B2758E66CF11"); //Windows Media
        FILE_TYPE_MAP.put("mid", "4D546864"); //MIDI (mid)
    }
}
